home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / pascal / tj50dsk1.zip / MENUTTT5.PAS < prev    next >
Pascal/Delphi Source File  |  1989-01-31  |  24KB  |  628 lines

  1. {--------------------------------------------------------------------------}
  2. {                         TechnoJock's Turbo Toolkit                       }
  3. {                                                                          }
  4. {                              Version   5.00                              }
  5. {                                                                          }
  6. {                                                                          }
  7. {              Copyright 1986, 1989 TechnoJock Software, Inc.              }
  8. {                           All Rights Reserved                            }
  9. {                          Restricted by License                           }
  10. {--------------------------------------------------------------------------}
  11.  
  12.                      {--------------------------------}                                       
  13.                      {       Unit:  MenuTTT5          }
  14.                      {--------------------------------}
  15.  
  16.  
  17. {$S-,R-,V-,D-}       
  18.  
  19. Unit MenuTTT5;
  20.  
  21. INTERFACE
  22.  
  23. Uses CRT, FastTTT5, DOS, WinTTT5, KeyTTT5, StrnTTT5;
  24.  
  25. const
  26.    Max_Choices = 30;
  27.    MenuStrLength = 40;     {make longer if necessary}
  28. type
  29. {$IFDEF VER50}
  30.    Menu_Hook = Procedure(var Ch:char; Choice:integer; var Ecode:integer);
  31. {$ENDIF}
  32.    Menu_record = record
  33.                   Heading1     : string[MenuStrLength];   { '' for no heading}
  34.                   Heading2     : string[MenuStrLength];
  35.                   Topic        : array[1..Max_Choices] of string[MenuStrLength];
  36.                   TotalPicks   : integer;
  37.                   PicksPerLine : byte;
  38.                   AddPrefix    : byte;                    {0 no, 1 No.'s, 2 Lets}
  39.                   TopLeftXY    : array[1..2] of byte;     {X,Y}
  40.                   Boxtype      : byte;                    {0,1,2,3, >3}
  41.                   Colors       : array[1..5] of byte;     {HF,HB,LF,LB,Box}
  42.                   Margins      : byte;
  43.                   AllowEsc     : boolean;                 {true if Esc will exit}
  44.                   {$IFDEF VER50}
  45.                   Hook         : Menu_hook;
  46.                   {$ENDIF}
  47.                 end;
  48. {$IFNDEF VER50}
  49. Var
  50.   M_UserHook : Pointer;
  51. {$ENDIF}
  52. Procedure No_Hook(var Ch:char; Choice:integer; var Ecode : integer);
  53. Procedure Menu_Set(var M : Menu_record);
  54. Procedure DisplayMenu(MenuDef: Menu_record;
  55.                       Window:Boolean;
  56.                       var Choice,Errorcode : integer);
  57.  
  58. IMPLEMENTATION
  59.  
  60. {$IFNDEF VER50}
  61.    Procedure Call_Hook(var Ch:char; Choice:integer; var Ecode:integer);
  62.           Inline($FF/$1E/M_UserHook);
  63. {$ENDIF}
  64.  
  65. {$F+}
  66.  Procedure No_Hook(var Ch:char; Choice:integer; var Ecode : integer);
  67.  {}
  68.  begin
  69.  end; {of proc No_Hook}
  70. {$F-}
  71.  
  72.  Procedure Menu_Set(var M : Menu_record);
  73.  {}
  74.  begin
  75.      with M do
  76.      begin
  77.          Heading1     := '';
  78.          Heading2     := '';
  79.          Topic[1]     := '';
  80.          TotalPicks   := 0;
  81.          PicksPerLine := 1;
  82.          AddPrefix    := 1;
  83.          TopLeftXY[1] := 0;
  84.          TopLeftXY[2] := 0;
  85.          Boxtype      := 5;
  86.          If BaseOfScreen = $B800 then
  87.          begin
  88.              Colors[1]    := white;
  89.              Colors[2]    := red;
  90.              Colors[3]    := lightgray;
  91.              Colors[4]    := blue;;
  92.              Colors[5]    := lightred;
  93.          end
  94.          else
  95.          begin
  96.              Colors[1]    := white;
  97.              Colors[2]    := black;
  98.              Colors[3]    := lightgray;
  99.              Colors[4]    := black;
  100.              Colors[5]    := white;
  101.          end;
  102.          Margins      := 5;
  103.          AllowEsc     := true;
  104.          {$IFDEF VER50}
  105.                  Hook         := NO_Hook;
  106.          {$ELSE}
  107.                  M_UserHook := Nil;
  108.          {$ENDIF}
  109.      end;
  110.  end; {of proc Menu_Set}
  111.  
  112.  Procedure MenuError(Code:byte);    {fatal error -- msg and halt}
  113.  var Message:string;
  114.  begin
  115.      {Clrscr;}
  116.      Case Code of
  117.      1 : Message := 'Fatal Error 1: Too Many Picks to display. Change PicksPerLine';
  118.      else Message := 'Aborting';
  119.      end; {case}
  120.      WriteAT(1,12,black,lightgray,Message);
  121.      Repeat Until keypressed;
  122.      Halt;
  123.  end;    {proc MenuError}
  124.  
  125. Procedure DisplayMenu(MenuDef: Menu_record;
  126.                       Window:Boolean;
  127.                       var Choice,Errorcode : integer);
  128. Const
  129. Alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  130. Numbers  = '123456789';
  131. var
  132. I,J,X2,Y2,heading_Lines : integer;
  133. TextWidth : byte;
  134.  
  135.  
  136.     Function Int_to_Str(Number:Integer):string;
  137.     var Temp : string;
  138.     begin
  139.        Str(Number,temp);
  140.        Int_to_Str := temp;
  141.     end;
  142.  
  143.     Function  Str_to_Int(Str:string):integer;
  144.     var temp,code : integer;
  145.     begin
  146.         If length(Str) = 0 then
  147.            Str_to_Int := 0
  148.         else
  149.         begin
  150.             val(Str,temp,code);
  151.             if code = 0 then
  152.                Str_to_Int := temp
  153.             else
  154.                Str_to_Int := 0;
  155.         end;
  156.     end;
  157.  
  158.    Procedure GetDimensions;
  159.    var Fullwidth,MaxWidth: integer;
  160.  
  161.      Procedure Validate_Prefix;                          { 0   no prefix  }
  162.      begin                                               { 1   numbers prefix}
  163.          with MenuDef do                                 { 2   letters prefix}
  164.          begin                                           { 3   function key prefix}
  165.              If PicksPerLine < 1 then PicksPerLine := 1; { 4   capital letter selection}
  166.              If (TotalPicks = 10) and (AddPrefix = 1) then
  167.                 AddPrefix := 3;
  168.              If (TotalPicks > 10) and (AddPrefix in [1,3]) then
  169.                 AddPrefix := 2;
  170.              If (Addprefix > 4) or (TotalPicks > 26) or (Addprefix < 0) then
  171.                 Addprefix := 0;
  172.              end; {do}
  173.      end; {Validate_Prefix}
  174.  
  175.    Procedure Add_Prefix;
  176.    var I : integer;
  177.    begin
  178.        With MenuDef do
  179.        begin
  180.            Case AddPrefix of
  181.            1 : for I := 1 to TotalPicks do
  182.                    Topic[I] := int_to_str(I) + ' ' + Topic[I];
  183.            2 : for I := 1 to TotalPicks do
  184.                    Topic[I] := Copy(Alphabet,I,1) + ' ' + Topic[I];
  185.            3 : If TotalPicks < 10 then
  186.                   for I := 1 to TotalPicks do
  187.                       Topic[I] := 'F'+Int_to_Str(I) + ' ' + Topic[I]
  188.                else
  189.                begin                           {add extra space for F10 }
  190.                    for I := 1 to 9 do
  191.                        Topic[I] := 'F'+Int_to_Str(I) + '  ' + Topic[I];
  192.                    Topic[10] := 'F10 '+ Topic[10];
  193.                end;
  194.            end; {case}
  195.        end;  {do}
  196.    end;  {proc Add_Prefix}
  197.  
  198.      Procedure Find_Longest_Topic;
  199.      var
  200.        I,J: integer;
  201.      begin
  202.          with MenuDef do
  203.          begin
  204.              Textwidth := 0;
  205.              For I := 1 to TotalPicks do
  206.                  If length(Topic[I]) > TextWidth then
  207.                     Textwidth := length(Topic[I]);         {find the longest text}
  208.          end;  {with}
  209.      end;   {Proc Find_Widest_Line}
  210.  
  211.    Procedure Adjust_Text_Width(Len:integer);
  212.    var I,J : integer;
  213.    begin
  214.        With MenuDef do
  215.        begin
  216.            For I := 1 to TotalPicks do
  217.                If length(Topic[I]) > Len then         {reduce it}
  218.                   Delete(Topic[I],succ(Len),length(Topic[I]) - Len)
  219.                else                                  {expand it}
  220.                   For J := length(Topic[I]) + 1 to Textwidth do
  221.                       Topic[I] :=  Topic[I] + ' ';
  222.        end; {do}
  223.    end;
  224.  
  225.    Procedure Determine_MaxWidth;
  226.    {findout the max internal menu space - MaxWidth}
  227.    begin
  228.        with MenuDef do
  229.        begin
  230.            If margins < 0 then Margins := 0;
  231.            If not (BoxType in [0..9]) then
  232.               BoxType := 0;
  233.            MaxWidth := 80 - 2*Margins - 1; {-1 for arrow symbol to left of pick}
  234.            Case BoxType of
  235.            1..4 : MaxWidth := MaxWidth - 2;     {box sides}
  236.            5    : MaxWidth := pred(MaxWidth);    {box shadow}
  237.            6..9 : MaxWidth := MaxWidth - 3;     {box sides and shadow}
  238.            end;
  239.        end; {with}
  240.    end;
  241.  
  242.    Procedure Validate_PicksPerLine;
  243.    begin
  244.        With MenuDef do
  245.        begin
  246.            If succ(TextWidth)*PicksPerLine <= MaxWidth then
  247.               exit;  {no adjustment necessary, everything fits}
  248.            If (TextWidth-2)*PicksPerLine <= Maxwidth  then
  249.                TextWidth := pred(MaxWidth div PicksperLine)
  250.            else
  251.            begin
  252.                While succ(TextWidth)*PicksPerLine > MaxWidth do
  253.                      PicksPerLine := pred(PicksPerLine);
  254.                If PicksPerLine = 0 then
  255.                begin
  256.                    TextWidth := pred(MaxWidth);
  257.                    PicksPerLine := 1;
  258.                end;
  259.            end;
  260.        end; {with}
  261.    end;  {Proc Validate_PicksPerLine}
  262.  
  263.    Procedure Determine_X_Dimensions;
  264.    {Checks to see if the menu will fit, if it won't it changes something!}
  265.    begin
  266.        With MenuDef do
  267.        begin
  268.            Fullwidth := succ(Textwidth)*PicksPerLine + 2*Margins;
  269.            Case BoxType of
  270.            1..4 : FullWidth := FullWidth + 2;     {box sides}
  271.            5    : FullWidth := succ(FullWidth);   {box shadow}
  272.            6..9 : FullWidth := FullWidth + 3;     {box sides and shadow}
  273.            end; {Case}
  274.            If TopleftXY[1] < 1 then
  275.               TopleftXY[1] := (80 - Fullwidth)  div 2;
  276.            If TopLeftXY[1] + Fullwidth < 80 then
  277.               X2 := TopleftXY[1] + Fullwidth
  278.            else
  279.            begin
  280.                X2 := 80;
  281.                TopLeftXY[1] := 80 - Fullwidth + 1;
  282.            end;
  283.        end; {with}
  284.    end; {Proc Determine_X_Dimensions}
  285.  
  286.    Procedure Determine_Y_Dimensions;
  287.    var
  288.       BoxLines,
  289.       TopicLines,
  290.       FullDepth  : integer;
  291.    begin
  292.        With MenuDef do
  293.        begin
  294.            TopicLines := TotalPicks div PicksPerLine;  {no of full rows of picks}
  295.            If TotalPicks mod PicksPerLine > 0 then     {+1 if partial row of picks}
  296.               TopicLines := succ(TopicLines);
  297.            Case BoxType of
  298.            0    : Boxlines := 0;
  299.            1..5 : BoxLines :=  2;     {box sides}
  300.            6..9: BoxLines :=  3;     {box sides and shadow}
  301.            end;
  302.            Heading_Lines := 0;
  303.            If length(Heading1) > 0 then
  304.               Heading_Lines := succ(Heading_Lines);
  305.            If length(Heading2) > 0 then
  306.               Heading_Lines := succ(Heading_Lines);
  307.            If Heading_Lines > 0 then                   {add a line for a gap}
  308.               Heading_Lines := succ(Heading_Lines);    {gap above topics}
  309.            If BoxType = 5 then
  310.               Heading_Lines := succ(Heading_Lines);
  311.            Fulldepth := BoxLines+TopicLines+Heading_Lines;
  312.            If Heading_Lines > 0 then
  313.              Fulldepth := succ(Fulldepth);  {+1 gap below topics if headings}
  314.            If FullDepth > DisplayLines then   {if it doesn't fit, drop off topics}
  315.            begin
  316.                If Heading_Lines > 0 then
  317.                   TotalPicks :=  (DisplayLines - BoxLines -Heading_Lines-1)*PicksPerLine
  318.                else
  319.                   TotalPicks :=  (DisplayLines - BoxLines - Heading_Lines)*PicksPerLine;
  320.                FullDepth := 25;
  321.            end;
  322.            If TopLeftXY[2] <= 0 then
  323.               TopLeftXY[2] := (DisplayLines - Fulldepth) div 2 +1;
  324.            If TopLeftXY[2] + Fulldepth - 1 <= DisplayLines then
  325.            begin
  326.                If BoxType > 4 then   {shadow}
  327.                   Y2 := TopleftXY[2] + (Fulldepth) - 1     {WZ}
  328.                else
  329.                   Y2 := TopleftXY[2] + (Fulldepth);        {WZ}
  330.            end
  331.            else
  332.            begin
  333.                If BoxType > 4 then   {shadow}
  334.                   Y2 := pred(DisplayLines)
  335.                else
  336.                   Y2 := DisplayLines;
  337.                TopLeftXY[2] := DisplayLines - Fulldepth {+ 1};   {WZ}
  338.            end;
  339.    end;   {do}
  340.    end; {Proc Determine_Y_Dimensions}
  341.  
  342.    begin                              {Get_Dimensions}
  343.        Validate_Prefix;
  344.        Add_Prefix;
  345.        Find_Longest_Topic;
  346.        Determine_MaxWidth;
  347.        Validate_PicksPerLine;
  348.        Adjust_Text_Width(TextWidth);
  349.        Determine_X_Dimensions;
  350.        Determine_Y_Dimensions;
  351.    end;   {proc GetDimensions}
  352.  
  353.    Procedure Write_Text(Item:integer;Highlight:boolean);
  354.    Var X,Y,A:integer;
  355.    begin
  356.        With MenuDEf do
  357.        begin
  358.            A := Item mod PicksPerLine;
  359.            Y := Item div PicksPerLine +TopleftXY[2] + ord(A <> 0);
  360.            Y := Y + Heading_lines - ord(Boxtype = 0);
  361.            If A = 0 then A := PicksPerLine;      {A is now the no of picks from left}
  362.            X := (A - 1)*(TextWidth + 1)+Margins+
  363.                 TopleftXY[1]+1 + ord(BoxType > 0);          {title width + 1 for a space}
  364.            If Highlight then
  365.            begin
  366.                WriteAt(X,Y,colors[1],colors[2],Topic[item]);
  367.                WriteAT(pred(X),Y,colors[5],colors[2],chr(16));  {write arrow head}
  368.            end
  369.            else
  370.            begin
  371.                WriteAT(X,Y,colors[3],colors[4],Topic[item]);
  372.                WriteAT(pred(X),Y,colors[3],colors[4],' ');       {remove arrow head}
  373.                If AddPrefix = 4 then                             {highlight the capital letter}
  374.                   WriteAT(Pred(X)+First_Capital_Pos(Topic[Item]),Y,
  375.                           colors[1],colors[4],
  376.                           First_Capital(Topic[Item]));
  377.            end;
  378.        end;  {do}
  379.    end;  {Proc Write_Text}
  380.  
  381.    Procedure CreateMenu;
  382.    var I : integer;
  383.    begin
  384.    with MenuDef do
  385.    begin
  386.     If Window then
  387.            MkWin(TopleftXY[1],TopLeftXY[2],X2,Y2,colors[3],colors[4],boxtype)
  388.     else
  389.     begin
  390.         ClearText(TopleftXY[1],TopLeftXY[2],X2,Y2,colors[3],colors[4]);
  391.         If (BoxType in [5..9]) and (TopleftXY[1] > 1) then      {draw a shadow}
  392.         begin
  393.             For I := TopleftXY[2]+1 to Y2+1 do
  394.                 WriteAt(pred(TopLeftXY[1]),I,colors[3],black,' ');
  395.             WriteAt(TopLeftXY[1],succ(Y2),colors[3],black,
  396.                 replicate(X2-succ(TopLeftXY[1]),' '));
  397.         end;
  398.     end;
  399.     Case Boxtype of
  400.     1..4: Box(TopLeftXY[1],TopLeftXY[2],X2,Y2,colors[5],colors[4],Boxtype);
  401.     5   : begin
  402.               WriteAT(TopleftXY[1],TopleftXY[2],colors[5],colors[4],
  403.                       replicate(succ(X2 - TopleftXY[1]),chr(223)));
  404.               WriteAT(TopleftXY[1],TopleftXY[2]+Heading_Lines-1,colors[5],colors[4],
  405.                       replicate(succ(X2 - TopleftXY[1]),chr(196)));
  406.           end;
  407.     6..9:Box(TopLeftXY[1],TopLeftXY[2],X2,Y2,colors[5],colors[4],Boxtype-5);
  408.     end; {case}
  409.  
  410.     If length(Heading1) > 0 then
  411.        WriteBetween(TopleftXY[1],X2,
  412.                     TopLeftXY[2]+ord(BoxType > 0),
  413.                     colors[1],colors[4],Heading1);
  414.     If length(Heading2) > 0 then
  415.        WriteBetween(TopleftXY[1],X2,
  416.                     TopLeftXY[2]+ord(BoxType > 0)+ord(Heading_Lines <> 2),
  417.                     colors[1],colors[4],Heading2);
  418.     For I := 1 to TotalPicks do
  419.         Write_Text(I,false);
  420.     Write_Text(Choice,True);       {Highlight Default}
  421.    end; {do}
  422.    end; {Proc CreateMenu}
  423.  
  424.    Procedure Process_Keystrokes;
  425.    var
  426.      Found,
  427.      Selected: Boolean;
  428.      ChT,
  429.      CHpk:char;
  430.      Oldchoice:integer;
  431.      I,
  432.      Ecode:integer;
  433.      ScanTop,ScanBot,Cx,Cy : byte;
  434.    begin
  435.        Selected := false;
  436.        Found := false;
  437.        FindCursor(Cx,Cy,ScanTop,ScanBot);
  438.        OffCursor;
  439.        With MenuDef do
  440.        begin
  441.        Repeat
  442.              Chpk := GetKey;
  443. {$IFDEF VER50}
  444.              MenuDef.Hook(Chpk,Choice,Ecode);   {call the user hook}
  445. {$ELSE}
  446.              If M_UserHook <> Nil then
  447.                 Call_Hook(Chpk,Choice,Ecode);
  448. {$ENDIF}
  449.              Case upcase(CHpk) of
  450.              #208 : begin       {Cursor Down}
  451.                         Write_text(Choice,false);
  452.                         Choice := Choice + PicksPerLine;
  453.                         If Choice > TotalPicks then
  454.                            Choice := (Choice mod PicksPerLine) + 1;
  455.                         Write_Text(Choice,true);
  456.                     end;
  457.              #129 : If Choice + PicksPerLine  <= TotalPicks then  {Mouse Down}
  458.                     begin
  459.                         Write_text(Choice,false);
  460.                         Choice := Choice + PicksPerLine;
  461.                         Write_Text(Choice,true);
  462.                     end;
  463.              #200 : begin       {cursor up}
  464.                         Write_Text(Choice,false);
  465.                         Choice := Choice - PicksPerLine;
  466.                         If Choice < 1 then
  467.                         begin
  468.                            Choice := Choice + PicksPerline;
  469.                            Choice :=
  470.                              ((TotalPicks div PicksPerLine)*PicksPerLine)
  471.                              - PicksPerLine + 1 + Choice - 2;
  472.                            If Choice + PicksPerLine <= TotalPicks then
  473.                               Choice := Choice + PicksPerLine;   {phew!}
  474.                         end;
  475.                         Write_Text(Choice,true);
  476.                     end;
  477.              #128 : If Choice - PicksPerLine > 0 then   {Mouse up}
  478.                     begin
  479.                         Write_Text(Choice,false);
  480.                         Choice := Choice - PicksPerLine;
  481.                         Write_Text(Choice,true);
  482.                     end;
  483.              #203 : begin       {cursor left}
  484.                         Write_Text(Choice,False);
  485.                         Choice := pred(choice);
  486.                         If choice = 0 then Choice := TotalPicks;
  487.                         Write_Text(Choice,true);
  488.                     end;
  489.              #130 : If (pred(Choice) > 0)  {mouse left}
  490.                     and ( Choice mod PicksPerLine <> 1) then
  491.                     begin
  492.                         Write_Text(Choice,False);
  493.                         Choice := pred(choice);
  494.                         Write_Text(Choice,true);
  495.                     end;
  496.              ' ',
  497.              #205 : begin        {cursor right}
  498.                         Write_Text(Choice,false);
  499.                         Choice := succ(Choice);
  500.                         If choice > TotalPicks then Choice := 1;
  501.                         Write_Text(Choice,true);
  502.                     end;
  503.              #131 : If (succ(Choice) <= TotalPicks) {Mouse right}
  504.                     and ( Choice mod PicksPerLine <> 0) then
  505.                     begin
  506.                         Write_Text(Choice,false);
  507.                         Choice := succ(Choice);
  508.                         Write_Text(Choice,true);
  509.                     end;
  510.              #199 : begin         {home key}
  511.                         Write_Text(Choice,false);
  512.                         Choice := 1;
  513.                         Write_Text(Choice,true);
  514.                     end;
  515.              #207 : begin         {end key}
  516.                         Write_Text(Choice,false);
  517.                         Choice := TotalPicks;
  518.                         Write_Text(Choice,true);
  519.                     end;
  520.              #133,                 {Mouse enter}
  521.              #13  : begin          {enter key}
  522.                         Selected := true;
  523.                         Errorcode := 0;
  524.                     end;
  525.              #0   : begin
  526.                         Selected := true;
  527.                         ErrorCode := Ecode;
  528.                     end;
  529.              #132,                    {Mouse Esc}
  530.              #27  : If AllowEsc then  {Esc}
  531.                     begin
  532.                         Selected := true;
  533.                         ErrorCode := 1;
  534.                     end
  535.                     else
  536.                     begin
  537.                         Write_Text(Choice,false);
  538.                         Choice := TotalPicks;
  539.                         Write_Text(Choice,true);
  540.                     end;
  541.              #187..#196 : If Addprefix = 3 then   {F1 to F10}
  542.                           begin
  543.                               Oldchoice := Choice;
  544.                               Case Upcase(Chpk) of
  545.                               #187 : If TotalPicks >= 1  then choice := 1 else choice := 0;
  546.                               #188 : If TotalPicks >= 2  then choice := 2 else choice := 0;
  547.                               #189 : If TotalPicks >= 3  then choice := 3 else choice := 0;
  548.                               #190 : If TotalPicks >= 4  then choice := 4 else choice := 0;
  549.                               #191 : If TotalPicks >= 5  then choice := 5 else choice := 0;
  550.                               #192 : If TotalPicks >= 6  then choice := 6 else choice := 0;
  551.                               #193 : If TotalPicks >= 7  then choice := 7 else choice := 0;
  552.                               #194 : If TotalPicks >= 8  then choice := 8 else choice := 0;
  553.                               #195 : If TotalPicks >= 9  then choice := 9 else choice := 0;
  554.                               #196 : If TotalPicks >= 10 then choice := 10 else choice := 0;
  555.                               end;  {case}
  556.                               If Choice = 0 then
  557.                                  Choice := Oldchoice
  558.                               else
  559.                               begin
  560.                                   Write_Text(Oldchoice,false);
  561.                                   Write_Text(Choice,true);
  562.                                   Selected := true;
  563.                                   Errorcode := 0;
  564.                               end;
  565.                           end;
  566.              '0'..'9': If (AddPrefix in [1,3]) then   {Number or Function Prefix} {4.02}
  567.                        begin
  568.                            If (Str_to_int(CHpk) in [1..TotalPicks]) then
  569.                            begin
  570.                                Write_Text(Choice,false);
  571.                                Choice := Str_to_Int(CHpk);
  572.                                Write_Text(Choice,true);
  573.                                Selected := true;
  574.                                ErrorCode := 0;
  575.                            end;
  576.                        end;
  577.              'A'..'Z': If AddPrefix = 2 then
  578.                        begin
  579.                           If (pos(upcase(CHpk),Alphabet) in [1..TotalPicks]) then
  580.                           begin
  581.                               Write_Text(Choice,false);
  582.                               Choice := pos(upcase(CHpk),Alphabet);
  583.                               Write_Text(Choice,true);
  584.                               Selected := true;
  585.                               Errorcode := 0;
  586.                           end;
  587.                        end
  588.                        else
  589.                        begin
  590.                            If AddPrefix = 4 then
  591.                            begin
  592.                                Found := false;
  593.                                I := Choice;
  594.                                Repeat
  595.                                     If First_Capital(Topic[I]) = upcase(ChPk) then
  596.                                     begin
  597.                                         Found := true;
  598.                                         Write_Text(Choice,false);
  599.                                         Choice := I;
  600.                                         Write_Text(Choice,true);
  601.                                         Selected := true;
  602.                                         Errorcode := 0;
  603.                                     end
  604.                                     else
  605.                                         If I = TotalPicks then
  606.                                            I := 1
  607.                                         else
  608.                                            Inc(I);
  609.                                Until Found or (I = Choice);
  610.                            end;
  611.                         end;
  612.                     end;
  613.        Until Selected;
  614.        SizeCursor(ScanTop,ScanBot);
  615.        end; {do}
  616.   end; {proc Process_keystrokes}
  617.  
  618. begin
  619.    GetDimensions;
  620.    CreateMenu;
  621.    Horiz_Sensitivity := 2;  {two cursors left/right before mouse returns a keypress}
  622.    Process_Keystrokes;
  623.    If Window then RmWin;
  624. end;        {Main Procedure DisplayMenu}
  625.  
  626. begin
  627. end.
  628.